/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cratos.xxgram.platf.notice;

import com.cratos.xxgram.platf.base.BaseService;
import com.cratos.xxgram.platf.base.RetCodes;
import com.cratos.xxgram.platf.base.UserInfo;
import com.cratos.xxgram.platf.rongcloud.RongCloudService;
import com.cratos.xxgram.platf.user.UserDetail;
import javax.annotation.Resource;
import org.redkale.source.Flipper;
import org.redkale.util.*;
import java.util.*;
import org.redkale.boot.Application;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.service.RetResult;
import org.redkale.source.FilterBean;

/**
 * 发送短信服务
 *
 *
 * @author zhangjx
 */
@Comment("短信服务")
@RestService(name = "sms", comment = "好友服务")
public class SmsService extends BaseService {

    private String signatureMethod = "HMAC-SHA1";

    @Resource(name = "property.aliyun.message.accesskeyid")
    private String accessKeyId = "LTAIaMLdX24UQDpt";

    @Resource(name = "property.aliyun.message.accesssecret")
    private String accessSecret = "JNEdjxw0Zg4Cw2UmnwPfKyBsNipDKl";

    @Resource(name = "property.aliyun.message.signname")
    private String signName = "Butter";

    private String signatureVersion = "1.0";
    @Resource(name = "property.aliyun.message.url")
    private String aliyunUrlPrefix = "http://dysmsapi.aliyuncs.com/?Signature=";

    private static final java.text.SimpleDateFormat DATE_FORMAT = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

    {
        DATE_FORMAT.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));// 这里一定要设置GMT时区
    }
    @Resource
    private JsonConvert convert = JsonConvert.root();

    public RetResult sendRandomSmsCode(short smstype, String mobile, int randomSmsCode) {
        return sendSmsRecord(smstype, mobile, randomSmsCode + "");
    }

    public RetResult sendSmsRecord(short smstype, String mobile, String content0) {
        final SmsRecord message = new SmsRecord(smstype, mobile, content0);
        RetResult result = null;
        try {
            Map<String, Object> param = new HashMap();
            param.put("code", content0);
            result = sendVerfilyCode(mobile, param); //测试注销
            //            result = RetResult.success();
            message.setStatus(SmsRecord.SMSSTATUS_SENDNO);
            if (result.isSuccess()) {
                message.setStatus(SmsRecord.SMSSTATUS_SENDOK);
            } else {
                message.setResultdesc(result.getRetinfo());
            }
            message.setSmsid(Utility.format36time(message.getCreatetime()) + Utility.uuid());
            source.insert(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Comment("查询短信记录列表")
    public Sheet<SmsRecord> querySmsRecord(@Comment("过滤条件") SmsBean bean, @Comment("翻页对象") Flipper flipper) {
        Flipper.sortIfAbsent(flipper, "createtime DESC");
        return source.querySheet(SmsRecord.class, flipper, bean);
    }

    @Comment("阿里云短信发送")
    public RetResult sendSms(String phoneNumbers, String templateCode, Map<String, Object> templateParam) {
        try {

            java.util.Map<String, String> paras = new java.util.HashMap<String, String>();
            // 1. 系统参数
            paras.put("SignatureMethod", signatureMethod);
            paras.put("SignatureNonce", java.util.UUID.randomUUID().toString());
            paras.put("AccessKeyId", accessKeyId);
            paras.put("SignatureVersion", signatureVersion);
            paras.put("Timestamp", DATE_FORMAT.format(new java.util.Date()));
            paras.put("Format", "JSON");
            // 2. 业务API参数
            paras.put("Action", "SendSms");
            paras.put("Version", "2017-05-25");
            paras.put("PhoneNumbers", phoneNumbers);
            paras.put("SignName", signName);
            paras.put("TemplateParam", JsonConvert.root().convertTo(templateParam));
            paras.put("TemplateCode", templateCode);
            // 3. 去除签名关键字Key
            if (paras.containsKey("Signature")) {
                paras.remove("Signature");
            }
            // 4. 参数KEY排序
            java.util.TreeMap<String, String> sortParas = new java.util.TreeMap<String, String>();
            sortParas.putAll(paras);
            // 5. 构造待签名的字符串
            java.util.Iterator<String> it = sortParas.keySet().iterator();
            StringBuilder sortQueryStringTmp = new StringBuilder();
            while (it.hasNext()) {
                String key = it.next();
                sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key)));
            }
            String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
            StringBuilder stringToSign = new StringBuilder();
            stringToSign.append("GET").append("&");
            stringToSign.append(specialUrlEncode("/")).append("&");
            stringToSign.append(specialUrlEncode(sortedQueryString));
            String sign = sign(accessSecret + "&", stringToSign.toString());
            // 6. 签名最后也要做特殊URL编码
            String signature = specialUrlEncode(sign);
            // 最终打印出合法GET请求的URL
            System.out.println(aliyunUrlPrefix + signature + sortQueryStringTmp);
            String getUrl = aliyunUrlPrefix + signature + sortQueryStringTmp;
            String response = Utility.getHttpContent(getUrl);
            System.out.println(response);
            AliyunResponse responseInfo = convert.convertFrom(AliyunResponse.class, response);
            logger.info(String.format("response ===== >>> %s", convert.convertTo(responseInfo)));
            if (!responseInfo.isSuccess()) {
                logger.finer(String.format("phoneNumbers = %s ,templateCode = %s ,TemplateParam =%s ,responseInfo = %s",
                        phoneNumbers,
                        templateCode,
                        convert.convertTo(templateParam),
                        convert.convertTo(responseInfo)));
                //无效的电话号码
                if (AliyunResponse.MOBIL_ILLEGAL.equalsIgnoreCase(responseInfo.getCode())) {
                    return RetCodes.retResult(RetCodes.RET_NOTIECE_MESSAGE_INVALID_MOBILE_NUM);
                }
                return RetCodes.retResult(RetCodes.RET_NOTIECE_MESSAGE_SEND_FAILD);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return RetResult.success();
    }

    public RetResult sendVerfilyCode(String phoneNumbers, Map<String, Object> templateParam) {
    	if (phoneNumbers.startsWith("861")) {
    		return sendSms(phoneNumbers, "SMS_177545798", templateParam); // 国内短信
    	}
    	// 鸡东
    	logger.finest("data ===" + phoneNumbers + ",code ...signName=" + signName);
    	return sendSms(phoneNumbers, "SMS_183768490", templateParam);
    }

    public static void main(String[] args) throws Exception {
        SmsService service = Application.singleton(SmsService.class);
        Map<String, Object> templateParam = new HashMap<>();
        templateParam.put("code", "123456");
        service.sendVerfilyCode("8613044889046", templateParam);
    }

    public static String specialUrlEncode(String value) throws Exception {
        return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
    }

    public static String sign(String accessSecret, String stringToSign) throws Exception {
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
        mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA1"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(signData);
    }

    public static class AliyunResponse {

        private static final String SUCCESS = "OK";

        private static final String MOBIL_ILLEGAL = "isv.MOBILE_NUMBER_ILLEGAL";

        public String Code;

        public String Message;

        public String getCode() {
            return Code;
        }

        public void setCode(String Code) {
            this.Code = Code;
        }

        @ConstructorParameters(value = {"Code", "Message"})
        public AliyunResponse(String Code, String Message) {
            this.Code = Code;
            this.Message = Message;
        }

        public String getMessage() {
            return Message;
        }

        public void setMessage(String Message) {
            this.Message = Message;
        }

        public boolean isSuccess() {
            return SUCCESS.equalsIgnoreCase(Code);
        }
    }
    //---------------------------------------------------------------------------
    @Resource
    private RongCloudService rongCloudService;

    @RestMapping(name = "synronyun", auth = false, comment = "同步融云初始化")
    public void synronyun() {
        Sheet<UserDetail> sheet = source.querySheet(UserDetail.class, null, new A());
        sheet.getRows().forEach(user -> {
            RetResult<String> rongrs = rongCloudService.insertUser(user);
            if (rongrs.isSuccess()) {
                System.out.println(rongrs.getResult());
                user.setRytoken(rongrs.getResult());
                user.setRytime(user.getCreatetime());
                source.updateColumn(user, "rytoken", "rytime");
            }
        });
       /**
        * 系统默认用户
        */
       UserInfo ui = new UserInfo();
       ui.setUserid(0);
       ui.setUsername("System0");
       rongCloudService.insertUser(ui);
       ui.setUserid(-1);
       ui.setUsername("System-1");
       rongCloudService.insertUser(ui);
       
    }

    public class A implements FilterBean {

    }
    //---------------------------------------------------------------------------
}
